require 'test/unit'
require 'engine/command'
require 'models/character'

class CharacterDatabase
    def add(c)
        @instances.add(c)
    end
end

class TCCommand < Command
    def initialize(executor)
        super(executor,"command","command <string>",
              "prints the <string> passed to the command")
    end
    def execute(params)
        raise UsageException if params.empty?
        "#{self.executor} goes #{params}!"
    end
end
class TCAdminCommand < Command
    RANK = 99
    def initialize(executor)
        super(executor,"admin","admin <string>",
              "prints the <string> passed to the admin")
    end
    def execute(params)
        raise UsageException if params.empty?
        "#{self.executor} goes #{params}!"
    end
end

class CommandEntityTest < Test::Unit::TestCase
    def setup
        @char = Character.new
        @char.oid = 1
        @char.name = 'Zero'
        CharacterDatabase.instance.add(@char)

        @cmd = TCCommand.new(@char)

        @cmd_char = Character.new
        @cmd_char.oid = 2
        @cmd_char.name = 'Hero'
        CharacterDatabase.instance.add(@cmd_char)

        @cmd2 = TCCommand.new(@cmd_char)
        @cmd_char.add_command(@cmd2)
    end
    def test_add_command
        @char.add_command(@cmd)
        assert_equal(1,@char.commands.size)

        @char.add_command(@cmd)
        assert_equal(1,@char.commands.size)
    end
    def test_del_command
        @char.add_command(@cmd)
        assert_equal(1,@char.commands.size)

        @char.del_command(@cmd)
        assert_equal(0,@char.commands.size)
    end
    def test_execute_command
        c = @cmd_char.find_command("command")
        assert_not_nil(c)
        assert_equal("Hero goes boom!",c.execute('boom'))
    end
    def test_usage
        err_msg = begin
            c = @cmd_char.find_command("command")
            c.execute('')
        rescue UsageException
            c.usage
        end
        assert_equal(err_msg,"command <string>")
    end

    def test_give_commands
        player = Character.new
        player.name = 'Player'
        player.oid = 1
        CharacterDatabase.instance.add(player)

        CommandDatabase.instance.add(:TCCommand)
        CommandDatabase.instance.add(:TCAdminCommand)

        # should NOT get the admin command
        CommandDatabase.instance.give_commands_to_player(player)
        assert_equal(1,player.commands.size)
        assert_equal("#{player.name} goes boom!",
                     player.find_command("command").execute("boom"))


        # should get the admin command
        player.rank = 99
        CommandDatabase.instance.give_commands_to_player(player)
        assert_equal(2,player.commands.size)
        assert_equal("#{player.name} goes boom!",
                     player.find_command("command").execute("boom"))
    end
end
